package io.vov.vitamio.tvpaser;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * 日期时间操作类
 * 
 */
public class DateUtil {

	/**
	 * 长日期格式: yyyy-MM-dd HH:mm:ss
	 */
	public static String DEFAULT_DATE_PARSE = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 时间长无特殊字符格式: yyyyMMddHHmmss
	 */
	public static String SPECIAL_TIME_PARSE = "yyyyMMddHHmmss";

	/**
	 * 短日期格式: yyyy-MM-dd
	 */
	public static String DEFAULT_SIMPLE_DATE_PARSE = "yyyy-MM-dd";

	/**
	 * 短日期格式: yyyy_MM_dd
	 */
	public static String DEFAULT_SIMPLE_DATE_FORMATER = "yyyy_MM_dd";
	
	/**
	 * 短日期格式：yyyy年MM月dd日 
	 */
	public static String SIMPLE_ZH_CN_DATE_FORMATER = "yyyy年MM月dd日";
	
	/**
	 * 日期格式：yyyy年MM月dd日  HH时mm分
	 */
	public static String ZH_CN_DATE_FORMATER = "yyyy年MM月dd日  HH时mm分";

	private static int[] MONTHDAYS = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

	/**
	 * 格式化字符串成日期,默认以{@link #DEFAULT_DATE_PARSE} 格式化。 如失败则以
	 * {@link #DEFAULT_SIMPLE_DATE_PARSE} 格式化。
	 * 
	 * @param dateStr
	 * @return
	 */
	public static Date parse(String dateStr) {
		if (StringUtil.isEmpty(dateStr)) {
			return null;
		}
		Date ret = parse(dateStr, DEFAULT_DATE_PARSE);
		if (ret == null) {
			ret = parse(dateStr, DEFAULT_SIMPLE_DATE_PARSE);
		}
		if (ret != null) {
			if (DateUtil.getDateFieldValue(ret, Calendar.YEAR) < 1753 || DateUtil.getDateFieldValue(ret, Calendar.YEAR) > 3000) {
				return null;
			}
		}
		return ret;
	}

	public static Date dateParse(String dateStr) {

		String year = dateStr.substring(0, dateStr.indexOf("-"));

		String month = dateStr.substring(dateStr.indexOf("-") + 1, dateStr.lastIndexOf("-"));
		String day = null;
		Calendar c1 = Calendar.getInstance();
		String hour = "";
		String min = "";
		String sec = "";
		if (dateStr.indexOf(":") > -1) {
			day = dateStr.substring(dateStr.lastIndexOf("-"), dateStr.indexOf(" "));

			int indexOfHour = dateStr.indexOf(":");
			int j = dateStr.lastIndexOf(":");

			hour = dateStr.substring(indexOfHour - 2, indexOfHour);
			min = dateStr.substring(indexOfHour + 1, j);
			sec = dateStr.substring(j + 1);

			c1.set(StringUtil.toInteger(1900 + year, 1900), StringUtil.toInteger(month, 1), StringUtil.toInteger(day, 1),
					StringUtil.toInteger(hour, 0), StringUtil.toInteger(min, 0), StringUtil.toInteger(sec, 0));
		} else {
			day = dateStr.substring(dateStr.lastIndexOf("-") + 1);
			// c1.set(StringUtil.toInteger(year, 1900), StringUtil
			// .toInteger(month, 1)-1, StringUtil.toInteger(day, 1));
		}
		c1.set(StringUtil.toInteger(year, 1900), StringUtil.toInteger(month, 1) - 1, StringUtil.toInteger(day, 1), StringUtil.toInteger(hour, 0),
				StringUtil.toInteger(min, 0), StringUtil.toInteger(sec, 0));
		return c1.getTime();
	}

	/**
	 * 以格式(yyyy-MM-dd HH:mm:ss)输出字符串
	 * 
	 * @param date
	 * @return
	 */
	public static String formatDate(Date date) {
		if (date == null) {
			return null;
		}

		SimpleDateFormat dateFormat = new SimpleDateFormat(DateUtil.DEFAULT_DATE_PARSE);
		return dateFormat.format(date);
	}

	/**
	 * 以给定日期格式输出字符串
	 * 
	 * @param date
	 * @param format
	 * @return
	 */
	public static String formatDate(Date date, String format) {
		if (date == null) {
			return null;
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		return dateFormat.format(date);
	}

	/**
	 * 以格式(yyyy_MM_dd)输出字符串
	 * 
	 * @param date
	 * @return
	 */
	public static String formatShort(Date date) {
		if (date == null) {
			return null;
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat(DateUtil.DEFAULT_SIMPLE_DATE_FORMATER);
		return dateFormat.format(date);
	}

	public static Date[] getCurrentMonth(Date currDate) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(currDate);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		Date fromDate = cal.getTime();

		cal.add(Calendar.MONTH, 1);
		cal.add(Calendar.DAY_OF_MONTH, -1);
		Date toDate = cal.getTime();
		return new Date[] { fromDate, toDate };
	}

	public static int getDateFieldValue(Date date, int field) {
		Calendar cl = Calendar.getInstance();

		cl.setTime(date);
		return cl.get(field);
	}

	public static Date parse(String dateStr, String format) {
		if (StringUtil.isEmpty(dateStr)) {
			return null;
		}

		SimpleDateFormat simpleDateParser = new SimpleDateFormat(DEFAULT_SIMPLE_DATE_PARSE, Locale.US);
		simpleDateParser.set2DigitYearStart(Timestamp.valueOf("2000-01-01 00:00:00.000000000"));
		simpleDateParser.setLenient(false);
		simpleDateParser.applyPattern(format);
		return simpleDateParser.parse(dateStr, new ParsePosition(0));
	}

	/**
	 * 将字符串以短日期格式化,如失败则返回null {@link #DEFAULT_SIMPLE_DATE_PARSE}
	 * 
	 * @param dateStr
	 * @param format
	 * @return
	 */
	public static Date parseShort(String dateStr) {
		if (StringUtil.isEmpty(dateStr)) {
			return null;
		}
		try {
			SimpleDateFormat simpleDateParser = new SimpleDateFormat(DEFAULT_SIMPLE_DATE_PARSE);
			return simpleDateParser.parse(dateStr);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}

	public static int getDayCountOfMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int month = cal.get(Calendar.MONTH);
		if (month == 1) {
			int year = cal.get(Calendar.YEAR);
			if (year % 4 == 0) {
				return 29;
			} else {
				return 28;
			}
		}
		return MONTHDAYS[month];
	}

	public static int getWeekDay(Date date) {
		if (date == null) {
			return -1;
		}

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);

		return getWeekDay(calendar.get(Calendar.DAY_OF_WEEK));
	}

	public static int getWeek(Date date) {
		if (date == null) {
			return -1;
		}

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);

		return calendar.get(Calendar.WEEK_OF_YEAR);
	}

	public static int getFirstDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.get(1);

		return 0;
	}

	public static int getWeekDay(int weekNumber) {
		switch (weekNumber) {
		case Calendar.MONDAY:
			return 1;

		case Calendar.TUESDAY:
			return 2;

		case Calendar.WEDNESDAY:
			return 3;

		case Calendar.THURSDAY:
			return 4;

		case Calendar.FRIDAY:
			return 5;

		case Calendar.SATURDAY:
			return 6;

		case Calendar.SUNDAY:
			return 0;

		default:
			return -1;
		}
	}

	public static int getDayOfMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);

		return cal.get(Calendar.DAY_OF_MONTH);
	}

	public static int getYear(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.YEAR);
	}

	public static Date getDate(int yyyy, int mm, int dd) {
		Calendar cal = Calendar.getInstance();

		cal.set(yyyy, mm, dd, 0, 0, 0);

		return cal.getTime();
	}

	/**
	 * 比较前一个日期是否晚于/或在同一天 后一个日期,返回true
	 * 
	 * @param originalDate
	 * @param compareDate
	 * @return
	 */
	public static boolean compareDate(Date originalDate, Date compareDate) {

		return originalDate.compareTo(compareDate) <= 0 ? true : false;

	}

	/**
	 * 把字符串格式{@link #DEFAULT_DATE_PARSE} 转换成 {@link #SPECIAL_TIME_PARSE}格式的字符串
	 * 
	 * @param time
	 * @return
	 */
	public static String parseTimestamp(String time) {
		if (StringUtil.isNull(time)) {
			return null;
		}
		Date date = DateUtil.parse(time, DateUtil.DEFAULT_DATE_PARSE);
		return DateUtil.formatDate(date, DateUtil.SPECIAL_TIME_PARSE);

	}
	
	static Date current_date = new Date();
	
	/**
	 * 解析动态时间格式,目前支持以下数据格式：
	 * null, "", "2011-12-11", "2011-12-15 17:54:09", "Sat, 10 Dec 2011 13:18:38 +0800", "Thu, 15 Dec 2011 07:48:27 GMT"
	 * @param time_str null or date format
	 * @return null or Date
	 */
	public static Date parseDynamicTime(String time_str) {

		Date last_date = null;
		try {
			last_date = new Date(time_str);
		} catch (IllegalArgumentException e) {
			// TODO: handle exception
			last_date = DateUtil.parse(time_str);
		} catch (NullPointerException ne) {
			throw ne;
		}

		return last_date;
	}
	
	/**
	 * 得到时间差文字说明
	 * @param curr_date 目前的日期
	 * @param comparer_date 要比较的日期
	 * @return
	 */
	public static String getDifftimeDesc(Date curr_date, Date comparer_date) {
		long d_value = curr_date.getTime() - comparer_date.getTime();
		if (d_value < 0) {
			return formatDate(comparer_date, ZH_CN_DATE_FORMATER);
		}
		d_value =  d_value/1000;
		if(d_value < 100){
			return "刚刚";
		}
		d_value =  d_value/60;
		if(d_value < 30){
			return d_value + "分钟前";
		}else if(d_value < 60){
			return "半小时前";
		}
		d_value = d_value/60;
		if(d_value < 24){
			return d_value + "小时前";
		}
		d_value = d_value/24;
		if(d_value < 15){
			return d_value + "天前";
		}else if(d_value < 30){
			return "半个月前";
		}
		d_value = d_value/30;
		if(d_value < 6){
			return d_value + "个月前";
		}
		return "很久以前";
	}
	
	
	public static void main(String[] args) {
		//2011-12-15 10:54:09
		//Sat, 10 Dec 2011 13:18:38 +0800
		//Thu, 15 Dec 2011 07:48:27 GMT
		 
//		Date date = new Date("2011-12-15 10:54:09");
//		System.out.println(date.toLocaleString() );
		
		
		System.out.println(parseDynamicTime(""));
		System.out.println(parseDynamicTime("2011-12-11"));
		System.out.println(parseDynamicTime("2011-12-15 17:54:09"));
		System.out.println(parseDynamicTime("Sat, 10 Dec 2011 13:18:38 +0800"));
		System.out.println(parseDynamicTime("11 Apr 2012 10:52:04 GMT"));
		System.out.println(parseDynamicTime(null));
		
		System.out.println(" getDifftimeDesc: " + getDifftimeDesc(new Date(), parseDynamicTime("11 Apr 2012 10:52:04 GMT")));
		System.out.println(" getDifftimeDesc: " + getDifftimeDesc(new Date(), parseDynamicTime("2011-12-22 12:11:09")));
		System.out.println(" getDifftimeDesc: " + getDifftimeDesc(new Date(), parseDynamicTime("2011-12-22 10:01:09")));
		System.out.println(" getDifftimeDesc: " + getDifftimeDesc(new Date(), parseDynamicTime("2011-12-21 12:12:09")));
		System.out.println(" getDifftimeDesc: " + getDifftimeDesc(new Date(), parseDynamicTime("2011-12-21 12:14:09")));
		System.out.println(" getDifftimeDesc: " + getDifftimeDesc(new Date(), parseDynamicTime("2011-12-21 14:01:09")));
		System.out.println(" getDifftimeDesc: " + getDifftimeDesc(new Date(), parseDynamicTime("2011-11-24 10:01:09")));
		System.out.println(" getDifftimeDesc: " + getDifftimeDesc(new Date(), parseDynamicTime("2011-11-14 10:01:09")));
		System.out.println(" getDifftimeDesc: " + getDifftimeDesc(new Date(), parseDynamicTime("2010-12-24 10:01:09")));
	}
	
}
